"use client";

import {
  AlertCircleIcon,
  CheckCircleIcon,
  FileArchiveIcon,
  FileIcon,
  FileSpreadsheetIcon,
  FileTextIcon,
  FileUpIcon,
  HeadphonesIcon,
  ImageIcon,
  LoaderIcon,
  RefreshCwIcon,
  VideoIcon,
  XIcon,
} from "lucide-react";

import {
  formatBytes,
  useFileUpload,
  type FileWithPreview,
} from "~/hooks/use-file-upload";
import { Button } from "~/components/ui/button";
import { forwardRef, useEffect, useImperativeHandle } from "react";
import type { UploadFunction } from "~/core/api/upload";

// 初始文件数组
const initialFiles: any[] = [];

interface MultipleFileUploaderProps {
  value?: FileWithPreview[];
  onChange?: (files: FileWithPreview[]) => void;
  maxFiles?: number;
  maxSize?: number;
  accept?: string;
  multiple?: boolean;
  autoUpload?: boolean;
  disabled?: boolean;
  className?: string;
  uploadFunction: UploadFunction;
  uploadParams?: Record<string, string>;
  onUploadComplete?: (
    fileId: string,
    result: { success: boolean; url?: string; error?: string },
  ) => void;
}

const getFileIcon = (file: { file: File | { type: string; name: string } }) => {
  const fileType = file.file instanceof File ? file.file.type : file.file.type;
  const fileName = file.file instanceof File ? file.file.name : file.file.name;

  if (fileType.startsWith("image/")) {
    return <ImageIcon className="size-4 text-blue-500" />;
  }
  if (fileType.startsWith("video/")) {
    return <VideoIcon className="size-4 text-purple-500" />;
  }
  if (fileType.startsWith("audio/")) {
    return <HeadphonesIcon className="size-4 text-green-500" />;
  }
  if (fileType === "application/pdf" || fileName.endsWith(".pdf")) {
    return <FileTextIcon className="size-4 text-red-500" />;
  }
  if (
    fileType.includes("spreadsheet") ||
    fileType.includes("excel") ||
    fileName.endsWith(".xlsx") ||
    fileName.endsWith(".xls") ||
    fileName.endsWith(".csv")
  ) {
    return <FileSpreadsheetIcon className="size-4 text-green-600" />;
  }
  if (
    fileType.includes("zip") ||
    fileType.includes("rar") ||
    fileType.includes("7z") ||
    fileName.endsWith(".zip") ||
    fileName.endsWith(".rar") ||
    fileName.endsWith(".7z")
  ) {
    return <FileArchiveIcon className="size-4 text-orange-500" />;
  }
  if (
    fileType.includes("text") ||
    fileName.endsWith(".txt") ||
    fileName.endsWith(".md") ||
    fileName.endsWith(".doc") ||
    fileName.endsWith(".docx")
  ) {
    return <FileTextIcon className="size-4 text-blue-600" />;
  }
  return <FileIcon className="size-4 text-gray-500" />;
};

const getUploadStatusIcon = (file: any) => {
  switch (file.uploadStatus) {
    case "uploading":
      return (
        <div className="flex items-center gap-2">
          <LoaderIcon className="size-4 animate-spin text-blue-500" />
          <span className="text-xs text-blue-500">
            {file.uploadProgress === 100 ? "解析" : "上传"}中...{" "}
            {file.uploadProgress ? `${file.uploadProgress}%` : ""}
          </span>
        </div>
      );
    case "success":
      return <CheckCircleIcon className="size-4 text-green-500" />;
    case "error":
      return <AlertCircleIcon className="size-4 text-red-500" />;
    default:
      return null;
  }
};

const ProgressBar = ({ progress }: { progress: number }) => (
  <div className="mt-1 h-1.5 w-full rounded-full bg-gray-200">
    <div
      className="h-1.5 rounded-full bg-blue-500 transition-all duration-300 ease-out"
      style={{ width: `${Math.min(progress, 100)}%` }}
    />
  </div>
);

const MultipleFileUploader = forwardRef<
  HTMLInputElement,
  MultipleFileUploaderProps
>(
  (
    {
      value = [],
      onChange,
      maxFiles = 100,
      maxSize = 100 * 1024 * 1024, // 100MB default
      accept = "*",
      multiple = true,
      autoUpload = true,
      disabled = false,
      className,
      uploadFunction,
      uploadParams,
      onUploadComplete,
    },
    ref,
  ) => {
    const [
      { files, isDragging, errors },
      {
        handleDragEnter,
        handleDragLeave,
        handleDragOver,
        handleDrop,
        openFileDialog,
        removeFile,
        clearFiles,
        retryUpload,
        getInputProps,
      },
    ] = useFileUpload({
      multiple,
      maxFiles,
      maxSize,
      accept,
      initialFiles: value.length > 0 ? value : initialFiles,
      autoUpload,
      uploadFunction,
      uploadParams,
      onFilesChange: onChange,
      onUploadComplete,
    });

    // 暴露input ref给FormField
    const inputProps = getInputProps();
    useImperativeHandle(ref, () => {
      if (
        inputProps.ref &&
        typeof inputProps.ref === "object" &&
        "current" in inputProps.ref &&
        inputProps.ref.current
      ) {
        return inputProps.ref.current;
      }
      // 返回一个空的HTMLInputElement来满足类型要求
      return document.createElement("input");
    }, [inputProps.ref]);

    // 当外部value变化时，同步内部状态
    useEffect(() => {
      if (value && value.length !== files.length) {
        // 这里可以添加同步逻辑，但通常useFileUpload会处理
      }
    }, [value, files.length]);

    return (
      <div className="flex flex-col gap-2">
        {/* Drop area */}
        <div
          role="button"
          onClick={openFileDialog}
          onDragEnter={handleDragEnter}
          onDragLeave={handleDragLeave}
          onDragOver={handleDragOver}
          onDrop={handleDrop}
          data-dragging={isDragging || undefined}
          className={`border-input hover:bg-accent/50 data-[dragging=true]:bg-accent/50 has-[input:focus]:border-ring has-[input:focus]:ring-ring/50 flex min-h-40 flex-col items-center justify-center rounded-xl border border-dashed p-4 transition-colors has-disabled:pointer-events-none has-disabled:opacity-50 has-[input:focus]:ring-[3px] ${disabled ? "pointer-events-none opacity-50" : ""} ${className || ""}`}
        >
          <input
            {...inputProps}
            className="sr-only"
            aria-label="上传文件"
            disabled={disabled}
          />

          <div className="flex flex-col items-center justify-center text-center">
            <div
              className="bg-background mb-2 flex size-11 shrink-0 items-center justify-center rounded-full border"
              aria-hidden="true"
            >
              <FileUpIcon className="size-4 opacity-60" />
            </div>
            <p className="mb-1.5 text-sm font-medium">上传文件</p>
            <p className="text-muted-foreground mb-2 text-xs">拖拽或点击浏览</p>
            <div className="text-muted-foreground/70 flex flex-wrap justify-center gap-1 text-xs">
              <span>所有文件</span>
              <span>∙</span>
              <span>最多 {maxFiles} 个文件</span>
              <span>∙</span>
              <span>最大 {formatBytes(maxSize)}</span>
            </div>
          </div>
        </div>

        {errors.length > 0 && (
          <div
            className="text-destructive flex items-center gap-1 text-xs"
            role="alert"
          >
            <AlertCircleIcon className="size-3 shrink-0" />
            <span>{errors[0]}</span>
          </div>
        )}

        {/* File list */}
        {files.length > 0 && (
          <div className="space-y-2">
            <div className="max-h-[328px] flex-col gap-2 overflow-y-auto not-last:flex">
              {files.map((file) => (
                <div
                  key={file.id}
                  className="bg-background flex items-center justify-between gap-2 rounded-lg border p-2 pe-3"
                >
                  <div className="flex flex-1 items-center gap-3 overflow-hidden">
                    <div className="flex aspect-square size-10 shrink-0 items-center justify-center rounded border">
                      {getFileIcon(file)}
                    </div>
                    <div className="flex min-w-0 flex-1 flex-col gap-0.5">
                      <div className="flex items-center gap-2">
                        <p className="truncate text-[13px] font-medium">
                          {file.file instanceof File
                            ? file.file.name
                            : file.file.name}
                        </p>
                        {file.uploadStatus !== "uploading" &&
                          getUploadStatusIcon(file)}
                      </div>
                      <div className="flex flex-col gap-1">
                        <div className="flex items-center gap-2">
                          <p className="text-muted-foreground text-xs">
                            {formatBytes(
                              file.file instanceof File
                                ? file.file.size
                                : file.file.size,
                            )}
                          </p>
                          {file.uploadStatus === "error" && (
                            <span className="text-xs text-red-500">
                              上传失败
                            </span>
                          )}
                        </div>
                        {file.uploadStatus === "uploading" &&
                          file.uploadProgress !== undefined && (
                            <ProgressBar progress={file.uploadProgress} />
                          )}
                      </div>
                    </div>
                  </div>

                  <div className="flex items-center gap-1">
                    {file.uploadStatus === "uploading" &&
                      getUploadStatusIcon(file)}
                    {file.uploadStatus === "error" && (
                      <Button
                        size="icon"
                        variant="ghost"
                        className="size-8 text-blue-500 hover:bg-blue-50 hover:text-blue-600"
                        onClick={() => retryUpload(file.id)}
                        disabled={disabled}
                        aria-label="重新上传"
                      >
                        <RefreshCwIcon className="size-4" aria-hidden="true" />
                      </Button>
                    )}
                    <Button
                      size="icon"
                      variant="ghost"
                      className="text-muted-foreground/80 hover:text-foreground -me-2 size-8 hover:bg-transparent"
                      onClick={() => removeFile(file.id)}
                      aria-label="删除文件"
                      disabled={disabled}
                    >
                      <XIcon className="size-4" aria-hidden="true" />
                    </Button>
                  </div>
                </div>
              ))}
            </div>

            {/* Remove all files button */}
            {files.length > 1 && (
              <div>
                <Button
                  size="sm"
                  variant="outline"
                  onClick={clearFiles}
                  disabled={disabled}
                >
                  删除所有文件
                </Button>
              </div>
            )}
          </div>
        )}
      </div>
    );
  },
);

MultipleFileUploader.displayName = "MultipleFileUploader";

export default MultipleFileUploader;
